package com.mtw.bbs.auth.controller;



import com.mtw.bbs.auth.pojo.TokenInfo;
import com.mtw.bbs.auth.provider.TokenProvider;
import com.mtw.bbs.auth.provider.TokenProviderBuilder;
import com.mtw.bbs.auth.service.AuthenticationService;
import com.mtw.bbs.common.core.constant.AuthConstant;
import com.mtw.bbs.common.core.exception.AuthException;
import com.mtw.bbs.common.core.security.UserDetails;
import com.mtw.bbs.common.core.vo.Result;
import com.mtw.bbs.userAdmin.pojo.dto.UserDto;
import io.swagger.annotations.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * 认证模块
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(value = "用户授权认证", tags = "授权接口")
public class AuthController {

    private final AuthenticationService authenticationService;





	@ApiOperation(value = "token合法性验证", notes = "token合法性验证,token合法，返回用户信息")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "string")
	})
	@ApiResponses(@ApiResponse(code = 200, message = "处理成功", response = Result.class))
	@PostMapping(value = "/validate")
	public Result validateAuth(@RequestBody Map<String, Object> param) {

		String token = (String)param.get("token");
		if (StringUtils.isBlank(token)){
			return Result.fail("token为空");
		}
		try {
			UserDto userDto = authenticationService.authentication(token);
			if (userDto == null){
				return Result.fail("登录信息错误");
			}
			UserDetails info = new UserDetails();
			BeanUtils.copyProperties(userDto,info);
			return Result.success(info);
		}catch (AuthException e){
			return Result.fail(e);
		}

	}


	@ApiOperation(value = "token续期", notes = "token续期，返回新token")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "string")
	})
	@ApiResponses(@ApiResponse(code = 200, message = "处理成功", response = Result.class))
	@PostMapping(value = "/refresh")
	public Result refreshToken(HttpServletRequest request) {


		String jwt = request.getHeader(AuthConstant.SERVICE_AUTH_KEY);
		if (StringUtils.isBlank(jwt)){
			return Result.fail("未登录！");
		}
		String refreshToken = request.getHeader(AuthConstant.REFRESH_TOKEN_HEADER);
		if (StringUtils.isBlank(refreshToken)){
			return Result.fail("token为空");
		}

		TokenProvider tokenProvider = TokenProviderBuilder.getTokenProvider("password");
		try {
			TokenInfo refresh = tokenProvider.refresh(jwt, refreshToken);
			return Result.success(refresh);
		}catch (AuthException e){
			return Result.fail(e);
		}

	}


	@ApiOperation(value = "权限验证", notes = "根据用户token，访问的url和method判断用户是否有权限访问")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "string"),
			@ApiImplicitParam(paramType = "query", name = "url", value = "访问的url", required = true, dataType = "string"),
			@ApiImplicitParam(paramType = "query", name = "method", value = "请求方式", required = true, dataType = "string")
	})
	@ApiResponses(@ApiResponse(code = 200, message = "处理成功", response = Result.class))
	@PostMapping(value = "/permission")
	public Result permission(@RequestBody Map<String, Object> param) {

		try {
			UserDto userDto = authenticationService.authentication(param);
			if (userDto == null){
				return Result.fail("登录信息错误");
			}
			UserDetails info = new UserDetails();
			BeanUtils.copyProperties(userDto,info);
			return Result.success(info);
		}catch (AuthException e){
			return Result.fail(e);
		}

	}



	@PostMapping("/logout")
	@ApiOperation(value = "登出")
	public Result logout(HttpServletRequest request) {

		String jwt = request.getHeader(AuthConstant.SERVICE_AUTH_KEY);

		if (StringUtils.isBlank(jwt)){
			return Result.fail("未登录！");
		}
		TokenProvider tokenProvider = TokenProviderBuilder.getTokenProvider("password");
		tokenProvider.logout(jwt);
		return Result.success();
	}




}
